﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Hydra.Shell.Interfaces;
using System.Windows.Media.Imaging;
using System.Threading;
using System.Windows.Threading;
using Hydra.Shell.Implementations;
using SLControlLibrary;
using System.Diagnostics;

namespace Hydra.Shell.Controls
{
    public partial class HydraStatusBar : UserControl, IHydraStatusBar
    {
        private int lastCookie;
        private int currentCookie = -1;
        private IHydraStatusbarUser currentUser;
        private DateTime lastCookieUpdate;
        private int currentComplete; 
        private int freezeCounter;
        private DispatcherTimer timer;
        private HydraServiceHandler<HydraStatusBar> handler;

        public HydraStatusBar()
        {
            handler = new HydraServiceHandler<HydraStatusBar>(new UIThread(this.Dispatcher), this);

            InitializeComponent();
        }

        public void Animation(bool fOnOff, BitmapImage pvIcon)
        {
            throw new NotImplementedException();
        }

        public void Clear()
        {
            this.Text.Content = "";
        }

        public void FreezeOutput(bool fFreeze)
        {
            if (fFreeze)
            {
                freezeCounter++;
            }
            else
            {
                freezeCounter--;
            }
        }

        public int FreezeCount
        {
            get 
            {
                return freezeCounter;
            }
        }

        string IHydraStatusBar.Text
        {
            get
            {
                return (string) this.Text.Content;
            }

            set
            {
                if (!this.IsFrozen && currentCookie == -1)
                {
                    this.Text.Content = value;
                }
            }
        }

        public bool IsCurrentUser(IHydraStatusbarUser pUser)
        {
            return pUser == currentUser;
        }

        public bool IsFrozen
        {
            get 
            {
                return freezeCounter != 0;
            }
        }

        public bool Progress(ref int pdwCookie, int fInProgress, string pwszLabel, int nComplete, int nTotal)
        {
            if (!this.IsFrozen)
            {
                if (pdwCookie != currentCookie && currentCookie != -1)
                {
                    return false;
                }
                else if (pdwCookie != 0 && currentCookie == -1)
                {
                    return false;
                }

                lastCookieUpdate = DateTime.Now;

                if (pdwCookie == 0)
                {
                    pdwCookie = ++lastCookie;
                    currentCookie = pdwCookie;

                    ProgressBar.Visibility = System.Windows.Visibility.Visible;

                    if (timer != null)
                    {
                        Debugger.Break();
                    }

                    timer = new DispatcherTimer();

                    timer.Tick += (sender, e) =>
                    {
                        if (DateTime.Now - lastCookieUpdate > TimeSpan.FromSeconds(30))
                        {
                            currentCookie = -1;

                            this.ProgressBar.Value = 0;
                            this.ProgressBar.Maximum = nTotal;

                            this.Text.Content = string.Empty;

                            timer.Stop();
                        }
                    };

                    timer.Interval = TimeSpan.FromSeconds(1);
                    timer.Start();
                }

                this.ProgressBar.Value = nComplete;
                this.ProgressBar.Maximum = nTotal;

                currentComplete = nComplete;

                this.Text.Content = pwszLabel;

                if (nComplete == nTotal)
                {
                    timer.Stop();

                    timer = new DispatcherTimer();

                    timer.Tick += (sender, e) =>
                    {
                        ProgressBar.Visibility = System.Windows.Visibility.Collapsed;
                        currentCookie = -1;

                        timer.Stop();
                        timer = null;
                    };

                    timer.Interval = TimeSpan.FromSeconds(1);
                    timer.Start();
                }

                return true;
            }
            else
            {
                return false;
            }
        }

        public void SetColorText(string pszText, Color crForeColor, Color crBackColor)
        {
            if (!this.IsFrozen && currentCookie != -1)
            {
                this.Text.Foreground = new SolidColorBrush(crForeColor);
                this.Text.Background = new SolidColorBrush(crBackColor);
            }
        }

        public void SetInsMode(Enumerations.InsertMode pvInsMode)
        {
            throw new NotImplementedException();
        }

        public void SetLineChar(object pvLine, object pvChar)
        {
            throw new NotImplementedException();
        }

        public void SetLineColChar(object pvLine, object pvCol, object pvChar)
        {
            throw new NotImplementedException();
        }

        public void SetSelMode(Enumerations.SelectionMode pvSelMode)
        {
            throw new NotImplementedException();
        }

        public string LegalText
        {
            get
            {
                return (string) this.Legal.Content;
            }
            set
            {
                if (!this.IsFrozen)
                {
                    this.Legal.Content = value;
                }
            }
        }

        public void SetXYWH(ref object pvX, ref object pvY, ref object pvW, ref object pvH)
        {
            throw new NotImplementedException();
        }

        public bool IsDisposed
        {
            get { throw new NotImplementedException(); }
        }

        public bool QueryInterface(Guid iid, out IUnknown interfaceObject)
        {
            return handler.QueryInterface(iid, out interfaceObject);
        }

        public bool QueryInterface<T>(out T interfaceObject)
        {
            return handler.QueryInterface<T>(out interfaceObject);
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            var parentControl = (Panel)this.Parent;

            this.Width = parentControl.ActualWidth;
            this.StatusBar.Width = parentControl.ActualWidth;
            this.StatusBarGrid.Width = parentControl.ActualWidth;

            parentControl.SizeChanged += (sender2, e2) =>
            {
                this.Width = parentControl.ActualWidth;
                this.StatusBar.Width = parentControl.ActualWidth;
                this.StatusBarGrid.Width = parentControl.ActualWidth;
            };
        }

        public bool QueryService<T>(Guid guidService, out ServiceLoadOperation<T> serviceLoadOperation) where T : IUnknown
        {
            return handler.QueryService<T>(guidService, out serviceLoadOperation);
        }

        public bool QueryService(Guid guidService, Guid guidInterFace, out ServiceLoadOperation serviceLoadOperation)
        {
            return handler.QueryService(guidService, guidInterFace, out serviceLoadOperation);
        }

        public int CurrentComplete
        {
            get 
            {
                return currentComplete;
            }
        }
    }
}
